import * as nodeFileSys from "fs";
import * as NSIconvLite from "iconv-lite";
import * as nodePath from "path";
import { TEST_S_CEL, getTravelBetween } from "./global-helper";
import { writeBufAsString, writeHanZiBufText, writeLastResult, writePinYinResult } from "./for-test";
import { getBinaryAsString, getCharCodeFrom, getCharCodeFromCoupleBuf, getCharNumFrom, getStringCharFrom, readAsCharCode } from "./binary-helper";

export interface Pin1_Yin1_Item {
  index: number,
  word: string,
}

function getHanZiOffset(buf: Uint8Array) {
  let result = buf[4];
  if (result === 68) {
    return 0x2628;
  }
  if (result === 69) {
    return 0x26c4;
  }
  throw new Error("不支持的文件类型(无法获取汉语词组的偏移量)");
}

function getFromU16(bufU16: Uint16Array, start: number, end: number): string {
  let subBufU16 = bufU16.slice(start, end);
  return NSIconvLite.decode(Buffer.from(subBufU16), "UTF-16LE");
}

function getIndexFrom(bufU16arr: Uint16Array): number {
  // let first = bufU16arr[0];
  let second = bufU16arr[1];
  let third = bufU16arr[2];
  if (third > 0) {
    return parseInt(
      third.toString().padStart(8, "0") +
      second.toString().padStart(8, "0"),
      2
    );
  }
  return second;
}

function getPinYinListFromU16(bufU16arr: Uint16Array): {
  end: number,
  arr: Array<Pin1_Yin1_Item>
} {
  let arr: Array<Pin1_Yin1_Item> = [];
  let len = bufU16arr.length;
  let registerIndex: Array<number> = [];
  let i = 0;
  for (; i < len;) {
    let index = getCharCodeFromCoupleBuf(bufU16arr.slice(i, i + 2))[0];
    let len = getCharCodeFromCoupleBuf(bufU16arr.slice(i + 2, i + 4))[0];
    let charList = getCharCodeFromCoupleBuf(bufU16arr.slice(i + 4, i + 4 + len));
    i = i + 4 + len;
    let word = String.fromCharCode(...charList);
    if (!registerIndex.includes(index)) {
      registerIndex.push(index);
      arr.push({
        index,
        word,
      });
    }
    if (word === "zuo") {
      break;
    }
  }
  return {
    end: i,
    arr,
  };
}


async function main() {
  let buf = await nodeFileSys.promises.readFile(TEST_S_CEL);
  let bufU8arr = new Uint8Array(buf);
  let hanZiOffset = getHanZiOffset(bufU8arr);
  let bufU16arr = new Uint16Array(buf);
  let title = getFromU16(bufU16arr, 0x130, 0x338);
  let category = getFromU16(bufU16arr, 0x338, 0x540);
  let desc = getFromU16(bufU16arr, 0x540, 0xd40);
  let samples = getFromU16(bufU16arr, 0xd40, 0x1540);
  console.log("title", title);
  console.log("category", category);
  console.log("desc", desc);
  console.log("samples", samples);
  let pinYinResult = getPinYinListFromU16(bufU16arr.slice(0x1544));
  let listPinYin = pinYinResult.arr;
  await writePinYinResult(listPinYin);
  let hanZiBuf = bufU16arr.slice(hanZiOffset);
  const charCode = getCharCodeFrom(bufU16arr[hanZiOffset], bufU16arr[hanZiOffset + 1]);
  await writeHanZiBufText(hanZiBuf);

  //#region handle_hanZi_buf
  let hanZiBufArray = Array.from(hanZiBuf);
  const resultList: Array<{
    pinYinList: string[],
    wordList: string[],
  }> = [];
  while (hanZiBufArray.length) {
    const wordCount = readAsCharCode(hanZiBufArray);
    const pinYinIndexCount = Math.floor(readAsCharCode(hanZiBufArray) / 2);
    const pinYinList: string[] = [];
    let isStop = getTravelBetween(pinYinIndexCount).some(() => {
      const pinYinIndex = readAsCharCode(hanZiBufArray);
      // console.log("pinYinIndex", pinYinIndex, pinYinIndexCount);
      const matchPinYin = pinYinResult.arr.find((item) => item.index === pinYinIndex);
      if (!matchPinYin) {
        return true;
      }
      pinYinList.push(matchPinYin.word);
      return false;
    });
    if (isStop) {
      console.log(pinYinList, wordCount);
      return;
    }
    const wordList: string[] = [];
    getTravelBetween(wordCount).some(() => {
      const wordLen = readAsCharCode(hanZiBufArray);
      let word = NSIconvLite.decode(Buffer.from(hanZiBufArray.slice(0, wordLen)), "UTF-16LE");
      wordList.push(word);
      hanZiBufArray = hanZiBufArray.slice(wordLen + 12);
      // console.log("ooo");
    });
    resultList.push({
      wordList,
      pinYinList,
    });
  }
  writeLastResult(resultList);
  let lastText = resultList.map((resultItem) => resultItem.wordList.join("\n")).join("\n");
  await nodeFileSys.promises.writeFile(
    nodePath.join(__dirname, "../result/result-word.txt"),
    lastText,
    "utf8"
  );
  //#endregion

  // getCharCodeFromCouple();
  // let bufU16HanZi = bufU16arr.slice(hanZiOffset);
}



main().catch((err) => {
  console.error(err);
});
